{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}

module Language.Dependencies.Adaptors.Python(
  languagepython,
  parPython,
  module Language.Python.Common.AST,
  module Generics.MultiRec.Languages.Python
) where

-- container
import Data.Tree (Tree(Node,rootLabel))

-- local imports
import Language.Dependencies.Language as L

import Language.Dependencies.Term2tree (data2tree)

import Data.ByteString.Char8(pack)

import Language.Python.Common.AST
import Language.Python.Common.SrcLocation as P
import Language.Python.Version2.Parser
import Generics.MultiRec.Languages.Python

languagepython = Language 
  { name         = "Python" 
  , syntax       = "Python" 
  , exts         = [".py"] 
  , parse        = parPython
  , toTree       = (data2tree TheModuleSpan :: ModuleSpan -> Tree String)
  , srcLoc       = tree2srcloc
  , adjustSrcLoc = Nothing
  , srcLoctype   = (Coordinate undefined undefined)
  , typerep = Just TheModuleSpan
  }

    
parPython :: String -> Either Error ModuleSpan
parPython s =
  case parseModule s "undef" of
    Right (m,ts)   -> Right m
    Left e -> Left $ ErrMessage (show e)


tree2srcloc :: Tree String -> [L.Loc]
tree2srcloc node = case (toSrcLoc node) of
  Just coordinate -> [coordinate]
  Nothing -> []


toSrcLoc :: Tree String -> Maybe L.Loc
toSrcLoc (Node "(,)" cs ) = Just $ fromSrcSpan $ SpanPoint
                                     (to cs 0)
                                     (read (to cs 1) :: Int)    -- row start
                                     (read (to cs 2) :: Int)    -- col start
toSrcLoc (Node "SpanPoint" cs) = Just $ fromSrcSpan $ SpanPoint
                                     (to cs 0)
                                     (read (to cs 1) :: Int)    -- row start
                                     (read (to cs 2) :: Int)    -- col start
toSrcLoc (Node "SpanCoLinear" cs) = Just $ fromSrcSpan $ SpanCoLinear 
                                     (to cs 0)
                                     ((read (to cs 1)) :: Int)  -- row start
                                     ((read (to cs 2)) :: Int)  -- col start
                                     ((read (to cs 3)) :: Int)  -- col end
toSrcLoc (Node "SpanMultiLine" cs) = Just $ fromSrcSpan $ SpanMultiLine
                                     (to cs 0)
                                     (read (to cs 1) :: Int)    -- row start
                                     (read (to cs 2) :: Int)    -- col start
                                     (read (to cs 3) :: Int)    -- row end
                                     (read (to cs 4) :: Int)    -- col end
toSrcLoc n@(Node l cs) = Nothing

fromSrcSpan :: SrcSpan -> L.Loc
-- fromSrcSpan (SpanEmpty) = Coordinate (-1,-1) (-1,-1)
fromSrcSpan (SpanPoint _ row col) = Coordinate (row,col) (row,col)
fromSrcSpan (SpanCoLinear _ row col _) = Coordinate (row,col) (row,col)
fromSrcSpan (SpanMultiLine _ row1 col1  row2 col2) = 
  Coordinate (row1,col1) (row2,col2)



-- Kommentar ? Was macht das ?
to :: [Tree String] -> Int -> String
to cs ix = rootLabel $ (cs !! ix)


